package cn.edu.swu.bc.servlet;

import cn.edu.swu.bc.filter.AuthFilter;
import cn.edu.swu.bc.utils.DBUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.nio.charset.Charset;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class SaveBlogServlet extends HttpServlet {

    private static final long serialVersionUID = 114876223236L;
    private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3;  // 3MB
    private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
    private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB
    private static final String PIC_DIRECTORY = "blogsPic";
    private static final String BLOG_DIRECTORY = "blogs";

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        this.doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String blog = "";
        String introduction = "";
        String title = null;
        String pics="";
        // 配置上传参数
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
        factory.setSizeThreshold(MEMORY_THRESHOLD);
        // 设置临时存储目录
        factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 设置最大文件上传值
        upload.setFileSizeMax(MAX_FILE_SIZE);
        // 设置最大请求值 (包含文件和表单数据)
        upload.setSizeMax(MAX_REQUEST_SIZE);
        // 中文处理
        upload.setHeaderEncoding("UTF-8");

        // 构造临时路径来存储上传的文件
        // 这个路径相对当前应用的目录
        String picUploadPath = request.getServletContext().getRealPath("./") + File.separator + PIC_DIRECTORY;
        String blogsUploadPath = request.getServletContext().getRealPath("./") + File.separator + BLOG_DIRECTORY;
        // 如果目录不存在则创建
        File uploadDir = new File(picUploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdir();
        }
        uploadDir = new File(blogsUploadPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdir();
        }
        try {
            // 解析请求的内容提取文件数据
            List<FileItem> formItems = upload.parseRequest(request);
            if (formItems != null && formItems.size() > 0) {
                // 迭代表单数据
                for (FileItem item : formItems) {
                    // 先处理非文本内容
                    if (!item.isFormField()) {
                        String fileName = new File(item.getName()).getName();
                        String filePath = picUploadPath + File.separator + fileName;
                        if (fileName.isEmpty())
                            continue;
                        File storeFile = new File(filePath);
                        // 在控制台输出文件的上传路径
                        System.out.println(filePath);
                        // 保存文件到硬盘
                        item.write(storeFile);
                        pics += fileName + ",";
                    } else {
                        if (item.getFieldName().equals("blog")) {
                            blog += item.getString("UTF-8");
                            blog += "\n";
                        } else if (item.getFieldName().equals("introduction")) {
                            introduction += item.getString("UTF-8");
                            introduction += "\n";
                        } else if (item.getFieldName().equals("title")) {
                            title = item.getString("UTF-8");
                        }
                    }
                }
            }
            HttpSession session = request.getSession();
            //从session中取出用户ID
            int UID = (Integer) session.getAttribute(AuthFilter.USER_ID);
            //更新数据库
            updateDatebase(blogsUploadPath, introduction + blog, UID, title, pics);
            response.sendRedirect("./blogs.html");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updateDatebase(String path, String blog, int UID, String title, String pics) throws IOException {
        String filename= createBlog(title,pics);
        insertUBtable(UID,Integer.parseInt(filename));
        SaveBlog(path,blog,filename);
    }
    private void SaveBlog(String path, String blogs, String filename) throws IOException {
        File storeFile = new File(path + File.separator + filename + ".txt");
        FileWriter fileWriter = new FileWriter(storeFile, Charset.forName("UTF-8"));
        fileWriter.write(blogs);
        fileWriter.close();
    }
    //在USER-BLOGS关系表中插入关系
    private void insertUBtable(int UID,int BID)
    {
        String sql= "insert into `users-blogs` values ("+UID+","+BID+");";
        try {
            DBUtils.insert(sql);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
    //在数据库中创建博客并返回其ID作为保存博客内容的文件名
    private String createBlog(String title,String pics)
    {
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        String datetime = dateFormat.format(date).toString();
        String insertBlog=null;
        if(pics.equals("")) {
            insertBlog =
                    String.format("insert into `blogs` (title,createtime,pics) values ('%s','%s',null);",
                            title, datetime);
        }
        else
            insertBlog =String.format("insert into `blogs` (title,createtime,pics) values ('%s','%s','%s');",
                    title, datetime,pics);
        String insertID=null;
        try {
            DBUtils.insert(insertBlog);
            insertID= DBUtils.getInsertBlogFileName();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return  insertID;
    }
}

